#ifndef SERVER_CONTROLLER_H
#define SERVER_CONTROLLER_H

#include <../network/Network.h>
#include "Model.h"

using namespace Network;

namespace Server {

/**
 * @brief Moduł odpowiedzialny za przekazywanie informacji odebranych z sieci do modelu serwera.
 *
 * Po odebraniu paczki danych rozpakowuje ją, wysyła zapytanie do modelu, a
 * następnie – po odebraniu odpowiedzi – pakuje ją w paczkę i wysyła z powrotem do
 * odpowiedniego klienta. Moduł ten sprawuje tez kontrolę nad czasem życia klientów. Jeśli
 * któryś z nich nie wyśle w określonym czasie informacji, że nadal jest aktywny, zostaje
 * wyrzucony z listy podłączonych klientów.
 **/
class Controller : public QObject
{
	Q_OBJECT

public:
	/**
	 * Konstruktor.
	 **/
        Controller();

	/**
	 * Destruktor
	 **/
	~Controller();

	/**
	 *
	 **/
	void start();

	/**
	 *
	 **/
	void stop();

private:

	/// Baza danych zawierająca spis udostępnianych plików
	Model * model;

	/// lista zalogowanych użytkowników
	QMap <int, RemoteClient*> clients_;

	/// kontroler sieci
	Network::Controller ncontroller;


	/**
	 * Reakcja na żądanie wyszukania plików.
	 *
	 * @param packet pakiet ptFind z żądaniem
	 *
	 * @return pakiet ptList z odpowiedzią na dane żądanie, bądx null w przypadku błędu
	 **/
	Packet * find(Packet * packet);

	/**
	 * Reakcja na żądanie wyszukania aktywnych posiadaczy danego pliku.
	 *
	 * @param packet pakiet ptFindSeeds z żądaniem
	 *
	 * @return pakiet ptListSeeds z odpowiedzią na dane żądanie, bądx null w przypadku błędu
	 **/
	Packet * findSeeds(Packet * packet);

	/**
	 * Reakcja na żądanie nadania nowego identyfikatora
	 **/
	Packet * idRequest(RemoteClient * client, Packet * packet);

	/**
	 * Logowanie klienta
	 *
	 * @param client klient, który się loguje
	 * @param packet pakiet logowania
	 **/
	Packet * login(RemoteClient * client, Packet * packet);

	/**
	 * Wylogowanie klienta
	 *
	 * @param client klient, który się wylogowuje (bądź z którym zostało zerwane połączenie)
	 * @param packet pakiet (jesli klient wylogowuje się normalnie)
	 *
	 * @return null
	 **/
	Packet * logout(RemoteClient * client, Packet * packet);

	/**
	 * Zmiana listy plików posiadanych przez klienta
	 *
	 * @return null
	 **/
	Packet * fileList(Packet * packet);


public slots:
	/**
	 * Z sieci odebrany został nowy pakiet. Jest on rozpakowywany, a następnie
	 * w zależności od typu przekazywany do odpowiednich metod. Po wykonaniu
	 * koniecznych operacji (odwołania do bazy danych itp), do klienta wysyłana
	 * jest odpowiedź (o ile istnieje taka konieczność).
	 *
	 * @param client klient, od którego odebrano pakiet
	 **/
	void onNewPacket(RemoteClient * client);

	/**
	 * Podłączył się nowy klient
	 *
	 * @param client wskazanie na nowego klienta
	 **/
	void onNewClient(RemoteClient * client);

	/**
	 * Połączenie z klientem zostało utracone
	 **/
	void onClientDied(RemoteClient * client);

signals:
	/**
	 * Komunikat wysyłany do systemu logującego zdarzenia.
	 *
	 * @param msg treść komunikatu
	 * @param type typ komunikatu
	 **/
	void newMsg(QString msg, int type);
};

} // namespace Server

#endif // SERVER_CONTROLLER_H
